package com.webrtc.demo.contacts

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemChildClickListener
import com.chad.library.adapter.base.listener.OnItemLongClickListener
import com.webrtc.demo.*
import com.webrtc.demo.call.*
import com.webrtc.demo.contacts.adapter.ContactsListAdapter
import com.webrtc.demo.model.Contacts
import com.webrtc.demo.util.ContactsUtils
import com.webrtc.demo.util.logD
import kotlinx.android.synthetic.main.activity_contacts_list.*
import kotlinx.coroutines.*
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions

class ContactsListActivity : AppCompatActivity(), OnItemChildClickListener,
    EasyPermissions.PermissionCallbacks, OnItemLongClickListener, CoroutineScope by MainScope(),
    OnFriendEventListener {

    companion object {
        private const val RC_CAMERA_AND_AUDIO = 1001
        private const val RC_ADD_CONTACTS = 1002
        private const val RC_SELECT_CONTACTS = 1003
        private const val RC_CREATE_CHAT_GROUP = 1004

    }

    private val adapter: ContactsListAdapter by lazy {
        ContactsListAdapter().apply {
            setOnItemLongClickListener(this@ContactsListActivity)
            setOnItemChildClickListener(this@ContactsListActivity)
        }
    }

    private lateinit var callToUid: String
    private var isCaller = true
    private var cId: String? = null
    private var selectedUidList: ArrayList<String>? = null
    private val connectionMap = mutableMapOf<Connection, (String) -> Unit>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_contacts_list)
        // 随机选择初始化wsurl
//        val wsUrl = WS_URLS.random()
        val wsUrl = RTCSignalClient.WS_URLS[0]
        supportActionBar?.title = wsUrl

        RTCSignalClient.init(ContactsUtils.getMyUid(this), wsUrl)
        ConnectionManager.init(application)

        RTCSignalClient.addOnFriendEventListener(this)
        ConnectionManager.addOnVideoCallListener { uid, cId ->
            runOnUiThread {
                AlertDialog.Builder(this@ContactsListActivity)
                    .setTitle("接受此联系人的视频邀请？")
                    .setMessage(uid)
                    .setPositiveButton("接受") { dialog, _ ->
                        callToUid = uid
                        this.cId = cId
                        isCaller = false
                        requiresPermissionsAfterCall()
                        dialog.dismiss()
                    }
                    .setNegativeButton("拒绝") { dialog, _ ->
                        dialog.dismiss()
                        if (cId == null) // 单人视频拒绝
                            RTCSignalClient.sendNegotiate(uid, Negotiate.DENY, MediaType.VIDEO) {
                                logD("RTCSignalClient", "已拒绝 $uid 的单人视频通话")
                            }
                        else { // 多人视频拒绝
                            RTCSignalClient.sendRoomNegotiate(uid, cId, RoomNegotiate.ROOM_DENY) {
                                logD("RTCSignalClient", "已拒绝 $uid 的多人视频通话")
                            }
                        }
                    }
                    .setCancelable(false)
                    .show()
            }
            true
        }

        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
        recyclerView.adapter = adapter

        loadData()

        // todo 测试群聊信令
        RTCSignalClient.addOnSignalEventListener(object : OnSignalEventListener {
            override fun onGroupJoinBroadcast(uid: String, newid: String, roomid: String): Boolean {
                launch {
                    Toast.makeText(
                        this@ContactsListActivity,
                        "$newid 加入群聊",
                        Toast.LENGTH_LONG
                    ).show()
                }
                return false
            }

            override fun onGroupNegotiate(
                uid: String,
                roomid: String,
                type: GroupNegotiate
            ): Boolean {
                launch {
                    if (type == GroupNegotiate.GROUP_CALL) {
                        AlertDialog.Builder(this@ContactsListActivity)
                            .setTitle("$uid 邀请你加入群聊")
                            .setPositiveButton("接受") { dialog, which ->
                                ChatGroupActivity.launch(
                                    this@ContactsListActivity,
                                    ArrayList(),
                                    roomid,
                                    uid
                                )
                                dialog.dismiss()
                            }
                            .setNegativeButton("拒绝") { dialog, which ->
                                dialog.dismiss()
                                RTCSignalClient.sendGroupNegotiate(
                                    uid,
                                    roomid,
                                    GroupNegotiate.GROUP_DENY
                                )

                            }
                            .show()
                    }
                }
                return true
            }
        })
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        val inflater = menuInflater
        inflater.inflate(R.menu.contacts_list_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.add -> {
                AddContactsActivity.launch(this, RC_ADD_CONTACTS)
                true
            }
            R.id.qrcode -> {
                MyNameCardActivity.launch(this)
                true
            }
            R.id.chat_group -> {
                ContactsSelectListActivity.launch(this, RC_CREATE_CHAT_GROUP)
                true
            }
            R.id.group -> {
                ContactsSelectListActivity.launch(this, RC_SELECT_CONTACTS)
                true
            }
            R.id.setting -> {
                AlertDialog.Builder(this)
                    .setTitle("选择信令服务器")
                    .setItems(RTCSignalClient.WS_URLS) { dialog, which ->
                        RTCSignalClient.init(
                            ContactsUtils.getMyUid(this),
                            RTCSignalClient.WS_URLS[which]
                        )
                        supportActionBar?.title = RTCSignalClient.WS_URLS[which]
                        dialog.dismiss()
                    }
                    .show()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onResume() {
        super.onResume()
        launch {
            // 从群聊回来之后重新添加
            delay(1000) // 延时。因为群聊页面onDestory在此页面onResume后面执行
            adapter.data.forEach { removeConnectionTextStationListener(it) } // 先移除TextStationListener
            adapter.data.forEach { addConnectionTextStationListener(it) }
        }
    }

    private fun loadData() {
        adapter.data.forEach { removeConnectionTextStationListener(it) } // 先移除TextStationListener
        val contactsList = ContactsUtils.getContactsList(this)
        adapter.setNewData(contactsList)
        contactsList?.forEach { addConnectionTextStationListener(it) }
    }

    private fun addConnectionTextStationListener(contacts: Contacts) {
        val connection = ConnectionManager.get(contacts.uid)
        val textListener: (String) -> Unit = { text ->
            launch {
                contacts.lastMessage = text
                adapter.notifyDataSetChanged()
            }
        }
        connection.textStation.registerListener(textListener)
        connectionMap[connection] = textListener
    }

    private fun removeConnectionTextStationListener(contacts: Contacts) {
        connectionMap.forEach {
            val connection = it.key
            if (connection.uid == contacts.uid) {
                connection.textStation.unregisterListener(it.value)
                return@forEach
            }
        }
    }

    private fun clearConnectionTextStationListener(contacts: Contacts) {
        connectionMap.forEach {
            val connection = it.key
            if (connection.uid == contacts.uid) {
                connection.textStation.close() // clear
                return@forEach
            }
        }
    }

    override fun onItemLongClick(
        adapter: BaseQuickAdapter<*, *>,
        view: View,
        position: Int
    ): Boolean {
        val item = adapter.getItem(position) as Contacts? ?: return false
        AlertDialog.Builder(this)
            .setTitle("删除此联系人？")
            .setMessage(item.uid)
            .setPositiveButton("确定") { dialog, _ ->
                ContactsUtils.removeContacts(this, item.uid)
                adapter.remove(position)
                dialog.dismiss()
                Toast.makeText(this, "联系人已删除", Toast.LENGTH_SHORT).show()
                clearConnectionTextStationListener(item) // 清除联系人设置的所有的TextStationListener
            }
            .setNegativeButton("取消") { dialog, _ ->
                dialog.dismiss()
            }
            .show()
        return true
    }

    override fun onItemChildClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
        val item = adapter.getItem(position) as Contacts? ?: return
        when (view.id) {
            R.id.messageIv -> {
                ChatActivity.launch(this, ContactsUtils.getMyUid(this), item.uid)
            }
            R.id.videoIv -> {
                callToUid = item.uid
                isCaller = true
                requiresPermissionsAfterCall()
            }
            R.id.editIv -> {
                val editText = EditText(this)
                editText.hint = "请输入昵称"
                AlertDialog.Builder(this)
                    .setTitle("昵称")
                    .setView(editText)
                    .setPositiveButton("确定") { dialog, _ ->
                        item.nickname = editText.text.toString()
                        adapter.notifyDataSetChanged()
                        val temp = item.lastMessage
                        item.lastMessage = null
                        ContactsUtils.saveContactsList(
                            this,
                            adapter.data as ArrayList<Contacts>
                        )
                        item.lastMessage = temp
                        dialog.dismiss()
                    }
                    .setNegativeButton("取消") { dialog, _ ->
                        dialog.dismiss()
                    }
                    .show()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_ADD_CONTACTS && resultCode == Activity.RESULT_OK) {
            loadData()
        } else if (requestCode == RC_SELECT_CONTACTS && resultCode == Activity.RESULT_OK) {
            selectedUidList = data!!.getStringArrayListExtra(ContactsSelectListActivity.EXTRA_DATA)
            if (selectedUidList?.isNotEmpty() == true) {
                requiresPermissionsAfterCall()
            }
        } else if (requestCode == RC_CREATE_CHAT_GROUP && resultCode == Activity.RESULT_OK) {
            selectedUidList = data!!.getStringArrayListExtra(ContactsSelectListActivity.EXTRA_DATA)
            if (selectedUidList?.isNotEmpty() == true) {
                ChatGroupActivity.launch(
                    this,
                    selectedUidList!!,
                    null,
                    null
                )
            }
        }
    }

    @AfterPermissionGranted(RC_CAMERA_AND_AUDIO)
    private fun requiresPermissionsAfterCall() {
        val perms = arrayOf(
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO
        )
        if (EasyPermissions.hasPermissions(this, *perms)) {
            when {
                selectedUidList != null -> MultiCallActivity.launch(
                    this,
                    selectedUidList!!,
                    null,
                    null
                )
                cId != null -> MultiCallActivity.launch(this, ArrayList(), cId, callToUid)
                else -> CallActivity.launch(
                    this,
                    ContactsUtils.getMyUid(this),
                    callToUid,
                    isCaller
                )
            }
            selectedUidList = null
            cId = null
        } else {
            EasyPermissions.requestPermissions(
                this,
                "Need permissions for camera & microphone",
                RC_CAMERA_AND_AUDIO,
                *perms
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
    }

    override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
    }

    override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
    }

    override fun onAddFriend(uid: String) {
        if (uid != ContactsUtils.getMyUid(this)) {
            val result = ContactsUtils.addContacts(this, uid)
            if (result) {
                launch {
                    Toast.makeText(
                        this@ContactsListActivity,
                        "你已添加" + uid + "为联系人",
                        Toast.LENGTH_LONG
                    ).show()
                    loadData()
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        connectionMap.forEach {
            it.key.close()
        }
        RTCSignalClient.disconnect()
    }

}